package com.lin.netty.module.channel;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;

/**
 * EventLoop
 * 一个EventLoop就是单独的一个worker（包含一个selector），处理一个channel所有的IO操作
 *
 * ChannelInitializer 通道初始化器
 * 它的作用是待客户端 SocketChannel 建立连接后（channel register注册到一个worker之后），执行 initChannel 以便添加更多的处理器
 *
 * pipeline 流水线
 * 多个handler组成一个流水线来处理数据，当一个事件（accept、read、write）触发时，
 * pipeline 负责发布事件（读、读取完成...）传播给每个 handler， handler 对自己感兴趣的事件进行处理（重写了相应事件处理方法）
 *
 * ChannelHandler
 * 处理一个I/O事件（accept、read、write）或拦截一个I/O操作，并将其转发到下一个处理程序它的{@link ChannelPipeline}。
 */
@Slf4j
public class ChannelFutureServer {
    public static void main(String[] args) {
        new ServerBootstrap()
                .group(new NioEventLoopGroup()) // 1 包含boss和worker的组
                .channel(NioServerSocketChannel.class) // 2 指定用ServerSocketChannel作为服务器的通道类型
                .childHandler(new ChannelInitializer<NioSocketChannel>() { // 3 添加handler
                    protected void initChannel(NioSocketChannel ch) {
                        log.info("接收到连接...");
                        ch.pipeline().addLast(new StringDecoder()); // 5
                        ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() { // 6
                            @Override
                            protected void channelRead0(ChannelHandlerContext ctx, String msg) {
                                log.debug("处理read事件...");
                                System.out.println(msg);
                            }
                        });
                    }
                })
                .bind(1122); // 4 服务器绑定端口
    }
}
